package com.huizhonglm.diap.core.upgrade;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Message;

import com.huizhonglm.diap.api.API;
import com.huizhonglm.diap.core.config.Constants;
import com.huizhonglm.diap.core.utils.LogUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 描述当前类的作用
 *
 * @author LiXiaoLong
 * @version 1.0
 * @since 2016-06-07 09:20
 */
public class DownloaderService extends Service {
    private final String TAG = "DownloaderService";
    private final int MSG_WHAT_START = 11;
    private final int MSG_WHAT_PROGRESS = 22;
    private final int MSG_WHAT_FINISH = 33;
    private final int MSG_WHAT_ERROR = 44;

    private DownloadHandler mHandler;

    private String localPath;
    private float fileSize;
    private float compSize;
    private long lastTime;

    private int notificationID;

    private String mode;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        fileSize = 0;
        compSize = 0;
        String url = intent.getStringExtra("download_url");
        localPath = intent.getStringExtra("local_path");
        mode = intent.getStringExtra("update_mode");
        notificationID = intent.getIntExtra("notification_id", 99999);

        LogUtil.print(TAG, "onStartCommand - url=" + url);
        LogUtil.print(TAG, "onStartCommand - path=" + localPath);
        LogUtil.print(TAG, "onStartCommand - id=" + notificationID);

        mHandler = new DownloadHandler(this);

        DownloadThread mThread = new DownloadThread(getFullURL(url), localPath);
        mThread.start();

        return super.onStartCommand(intent, flags, startId);
    }

    private String getFullURL(String url){
        if (!url.startsWith("http://") &&
                !url.startsWith("HTTP://") &&
                !url.startsWith("file://") &&
                !url.startsWith("FILE://") &&
                !url.startsWith("content://") &&
                !url.startsWith("CONTENT://")) {

            return API.HOST + "/" + url;
        }
        return url;
    }

    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_WHAT_START:
                Intent broadcastStart = new Intent(Constants.UPGRADE_DOWNLOADER_SERVICE_START);
                broadcastStart.putExtra("mode", mode);
                broadcastStart.putExtra("notificationID", notificationID);
                sendBroadcast(broadcastStart);
                break;
            case MSG_WHAT_PROGRESS:
                float percent = (compSize / fileSize) * 100.0f;
                LogUtil.print(TAG, "progress - percent=" + percent);
                Intent broadcastPro = new Intent(Constants.UPGRADE_DOWNLOADER_SERVICE_PROGRESS);
                broadcastPro.putExtra("mode", mode);
                broadcastPro.putExtra("notificationID", notificationID);
                broadcastPro.putExtra("fileSize", fileSize);
                broadcastPro.putExtra("compSize", compSize);
                sendBroadcast(broadcastPro);
                break;
            case MSG_WHAT_FINISH:
                Intent broadcastFinish = new Intent(Constants.UPGRADE_DOWNLOADER_SERVICE_FINISH);
                broadcastFinish.putExtra("mode", mode);
                broadcastFinish.putExtra("notificationID", notificationID);
                broadcastFinish.putExtra("localPath", localPath);
                sendBroadcast(broadcastFinish);
                stopSelf();
                break;
            case MSG_WHAT_ERROR:
                Intent broadcastError = new Intent(Constants.UPGRADE_DOWNLOADER_SERVICE_ERROR);
                broadcastError.putExtra("mode", mode);
                broadcastError.putExtra("notificationID", notificationID);
                sendBroadcast(broadcastError);
                stopSelf();
                break;
        }
    }

    public static class DownloadHandler extends android.os.Handler {
        private WeakReference<DownloaderService> wrf;

        public DownloadHandler(DownloaderService clz) {
            this.wrf = new WeakReference<>(clz);
        }

        @Override
        public void handleMessage(Message msg) {
            DownloaderService the = wrf.get();
            if (the != null) {
                the.handleMessage(msg);
            }
        }
    }

    public class DownloadThread extends Thread {

        private String fileUrl;
        private String filePath;

        public DownloadThread(String url, String path) {
            this.fileUrl = url;
            this.filePath = path;
        }

        @Override
        public void run() {
            InputStream is = null;
            FileOutputStream fos = null;
            HttpURLConnection conn = null;
            try{
                //创建按一个URL实例
                URL url = new URL(fileUrl);
                //创建一个HttpURLConnection的链接对象
                conn = (HttpURLConnection) url.openConnection();
                fileSize = conn.getContentLength();
                mHandler.sendEmptyMessage(MSG_WHAT_START);
                //获取所下载文件的InputStream对象
                is = conn.getInputStream();
                //在指定目录创建一个空文件并获取文件对象
                File file = new File(filePath);
                //获取一个写入文件流对象
                fos = new FileOutputStream(file);
                //创建一个4*1024大小的字节数组，作为循环读取字节流的临时存储空
                byte buffer[] = new byte[4096];
                //循环读取下载的文件到buffer对象数组中
                int length;
                while ((length = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, length);
                    onProgress(length);
                }
                mHandler.sendEmptyMessage(MSG_WHAT_FINISH);
            }catch (Exception e) {
                e.printStackTrace();
                mHandler.sendEmptyMessage(MSG_WHAT_ERROR);
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                    if (is != null) {
                        is.close();
                    }
                    if (conn != null) {
                        conn.disconnect();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        private void onProgress(int length){
            compSize += length;
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastTime > 500) {
                Message msg = Message.obtain();
                msg.what = MSG_WHAT_PROGRESS;
                mHandler.sendMessage(msg);
                lastTime = currentTime;
            }
        }
    }

}
